"""


    Mk2Control - Hercules DJ Console Mk2 as Live Control Surface

    
"""

# site import

# Live imports
try:
    import Live
    from _Framework.ControlSurfaceComponent import ControlSurfaceComponent
    import _Framework.ClipSlotComponent as ClipSlotComponent
    import _Framework.ButtonElement as ButtonElement
    from VCM600.ViewTogglerComponent import ViewTogglerComponent 
except:
    import PAL.LiveMock as Live
    from PAL._FrameworkMock.ControlSurfaceComponent import ControlSurfaceComponent
    import PAL._Framework.ClipSlotComponent as ClipSlotComponent
    import PAL._FrameworkMock.ButtonElement as ButtonElement
    
# PAL imports
import PAL.liveControl
#import pal_config

####################################################################################
####################################################################################
####################################################################################
class Mk2Control(PAL.liveControl.LiveControl):
    def __init__( self, c_instance, name=None ):
        PAL.liveControl.LiveControl.__init__( self, c_instance, name )

        self.playComponentA = PlayComponent(0, 8, 0)
        self.playComponentB = PlayComponent(1, 2, 5)
        self._setup_view_control()
        
    def _setup_view_control(self):
        is_momentary = True
        channel = 0
        NUM_TRACKS = 2
        self.tglview = MyViewTogglerComponent(NUM_TRACKS)
        self.tglview.set_buttons(
            ( 
                MyButt(is_momentary, ButtonElement.MIDI_CC_TYPE, 0, 19), 
                MyButt(is_momentary, ButtonElement.MIDI_CC_TYPE, 0, 23), 
            ),
            ( 
                MyButt(is_momentary, ButtonElement.MIDI_CC_TYPE, 0, 20), 
                MyButt(is_momentary, ButtonElement.MIDI_CC_TYPE, 0, 24), 
            ),
        )
        
####################################################################################
####################################################################################
####################################################################################
class MyButt(ButtonElement.ButtonElement):
    pass #def send_value(self, value):
        #print "------------------------MY SEND VALUE",1,repr(value)
        #ButtonElement.ButtonElement.send_value(self, value)
        #print "------------------------MY SEND VALUE",2

class MyViewTogglerComponent(ViewTogglerComponent):
    def select_playing_clip_int_track(self,track):
        print "..............select_playing_clip_int_track"
        i = 0
        for cs in track.clip_slots:
            if cs.clip is not None and (cs.clip.is_playing or cs.clip.is_triggered):
                #print '\nS '.join(dir( self.song().view ))
                #print '\nA '.join(dir( Live.Application.get_application().view ))
                self.song().view.selected_scene = self.song().scenes[i]
                return 
            i += 1
            
    #def _chain_value(self, value, sender):
    #    print '!!!!! _chain_value !!!!!'
    #    return ViewTogglerComponent._chain_value(self,value,sender)

    def _clip_value(self, value, sender):
        #print '!!!!! _clip_value !!!!!', 
        assert (sender in self._clip_buttons)
        if ((not sender.is_momentary()) or (value != 0)):
            index = list(self._clip_buttons).index(sender)
            self._ignore_track_selection = True
            if (len(self.song().tracks) > index):
                track = self.song().tracks[index]
                self.select_playing_clip_int_track(track)
                if (self.song().view.selected_track != track):
                    self.song().view.selected_track = track
                    if ((not self.application().view.is_view_visible('Detail')) or (not self.application().view.is_view_visible('Detail/Clip'))):
                        self.application().view.show_view('Detail')
                        self.application().view.show_view('Detail/Clip')
                elif (self.application().view.is_view_visible('Detail/Clip') and self.application().view.is_view_visible('Detail')):
                    self.application().view.hide_view('Detail')
                else:
                    self.application().view.show_view('Detail')
                    self.application().view.show_view('Detail/Clip')
            self._ignore_track_selection = False

    #def _update_buttons(self):
    #    print "MY UPDATE",1
    #    ViewTogglerComponent._update_buttons(self)
    #    print "MY UPDATE",2

####################################################################################
####################################################################################
####################################################################################
class PlayComponent( ClipSlotComponent.ClipSlotComponent ):
    def __init__( self, trackIndex, on_cc_no, blink_cc_no ):
        ClipSlotComponent.ClipSlotComponent.__init__( self )
        self.trackIndex = trackIndex
        self.set_stopped_value(0)
        self.set_triggered_to_play_value(1)
        self.set_triggered_to_record_value(2)
        self.set_started_value(3)
        self.set_recording_value(4)
        
        self.select_playing_clip()
        self.set_launch_button(PlayButt(on_cc_no, blink_cc_no))

    def select_playing_clip(self):
        track = Live.Application.get_application().get_document().tracks[self.trackIndex]
        i = 0
        for cs in track.clip_slots:
            if cs.clip is not None and (cs.clip.is_playing or cs.clip.is_triggered):
                self.set_clip_slot( cs )
                return
        self.set_clip_slot( track.clip_slots[0] )

    def _launch_value(self, value):
        if not self.is_enabled():
            return
        if self._clip_slot is None:
            return
        if not value:
            return
        if not self.has_clip():
            self._clip_slot.fire() # stop...
            return

        if not Live.Application.get_application().get_document().is_playing:
            self._clip_slot.clip.set_fire_button_state(True)
            return
            
        if self._clip_slot.clip.is_playing:
            self._clip_slot.stop()
        else:
            self._clip_slot.clip.set_fire_button_state(True)
        self.select_playing_clip()


####################################################################################
####################################################################################
####################################################################################
class PlayButt(ButtonElement.ButtonElement):
    def __init__(self, on_cc_no, blink_cc_no ):
        self.on_cc_no = on_cc_no
        self.blink_cc_no = blink_cc_no 
        ButtonElement.ButtonElement.__init__(
            self, 
            is_momentary=True, # does it send midi on release ? 
            msg_type=ButtonElement.MIDI_CC_TYPE, 
            channel=0, 
            identifier=on_cc_no
        )

    def send_value(self, value):
        """
        send a value to the DEVICE
        this is called by the ClipSlotComponent when clips slot status
        has changed
        """
        print "###### send butt value", value
        on_cc_no = self.on_cc_no
        blink_cc_no = self.blink_cc_no
        status_byte = self.status_byte()
        self.send_midi( (status_byte, blink_cc_no, 0 ) )
        self.send_midi( (status_byte, on_cc_no, 0 ) )
        if 0 and value == 0:
            print "reset"
            self.send_midi( (status_byte, blink_cc_no, 127 ) )
        elif value == 1:
            print "trigger play"
            self.send_midi( (status_byte, blink_cc_no, 127 ) )
        elif value == 2:
            print "trigger rec"
            self.send_midi( (status_byte, blink_cc_no, 127 ) )
        elif value == 3:
            print "play"
            self.send_midi( (status_byte, on_cc_no, 127 ) )
        elif value == 4:
            print "rec"
            self.send_midi( (status_byte, on_cc_no, 127 ) )

    #def message_map_mode(self):
    #    assert (self.message_type() is MIDI_CC_TYPE)
    #    return Live.MidiMap.MapMode.absolute


####################################################################################
####################################################################################
####################################################################################
class Mk2Component(ControlSurfaceComponent):
    def __init__(self):
        ControlSurfaceComponent.__init__( self )

    def disconnect(self):
        print "disconnect"

    def update(self):
        print "update"

    def on_enabled_changed(self):
        print "on_enabled_changed"

    def on_track_list_changed(self):
        """ Called by the control surface if tracks are added/removed, to be overridden """
        print "on_track_list_changed"

    def on_scene_list_changed(self):
        """ Called by the control surface if scenes are added/removed, to be overridden """
        print "on_scene_list_changed"

    def on_selected_track_changed(self):
        """ Called by the control surface when a track is selected, to be overridden """
        print "on_selected_track_changed"

    def on_selected_scene_changed(self):
        """ Called by the control surface when a scene is selected, to be overridden """
        print "on_selected_scene_changed"
